package com.googlecode.animator.controller
{
	import com.googlecode.animator.controller.mediators.SWFLoaderMediator;
	import com.googlecode.animator.controller.mediators.VideoStreamMediator;
	import com.googlecode.animator.view.specialmaterials.TextMaterial;
	import com.googlecode.data.materials.BitmapFileMaterialVO;
	import com.googlecode.data.materials.ColorMaterialVO;
	import com.googlecode.data.materials.MaterialVO;
	import com.googlecode.data.materials.MovieMaterialVO;
	import com.googlecode.data.materials.TextMaterialVO;
	import com.googlecode.data.materials.VideoStreamMaterialVO;
	import com.googlecode.data.objects3d.CubeVO;
	import com.googlecode.data.objects3d.MaterialsListObject3DVO;
	import com.googlecode.data.objects3d.Object3DVO;
	import com.googlecode.data.objects3d.PlaneVO;
	import com.googlecode.data.objects3d.SingleMaterialObject3DVO;
	import com.googlecode.utils.ResolveFilePath;
	
	import flash.geom.Point;
	import flash.utils.Dictionary;
	
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.materials.BitmapFileMaterial;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.objects.primitives.Plane;
	import org.puremvc.as3.multicore.interfaces.INotification;
	
	
	/**
	 * Handles a change to an Object3D's material. 
	 * @author USER
	 * 
	 */
	public class UpdateMaterialCommand extends BaseCommand
	{
		private var _object3D:Object3DVO;
		
		private var _resolve:ResolveFilePath;
		
		/**
		 * Executes command. 
		 * @param notification
		 * 
		 */
		override public function execute(notification:INotification):void
		{
			super.execute(notification);
			
			var mat:MaterialVO;
			
			_resolve = ResolveFilePath.instance;
			
			_object3D = notification.getBody() as Object3DVO;

			var object3DinScene:DisplayObject3D = settings.scene.getChildByName(_object3D.name);
			
			if(_object3D is SingleMaterialObject3DVO)
			{
				mat = (_object3D as SingleMaterialObject3DVO).material;
				if(getMaterial(mat) != null)
				{
					object3DinScene.material = getMaterial(mat);		
				}
			}

			if(_object3D is MaterialsListObject3DVO)
			{
				
				var mList:Dictionary = (_object3D as MaterialsListObject3DVO).materialsList;
				mat = mList[(_object3D as MaterialsListObject3DVO).selectedFace];
				
				if(getMaterial(mat) != null)
				{
					object3DinScene.replaceMaterialByName(getMaterial(mat), (_object3D as MaterialsListObject3DVO).selectedFace);
				}
				
			}
			
			settings.setObject3DMaterial(_object3D); 	
		}
		
		/**
		 * Returns the actual material needed for the object3D. 
		 * @param matVO
		 * @return 
		 * 
		 */
		protected function getMaterial(matVO:MaterialVO):*
		{
			var material:*;
			
			if(matVO is BitmapFileMaterialVO)
			{
				material = new BitmapFileMaterial(_resolve.getPath(matVO as BitmapFileMaterialVO, settings.savePath));
				
				return material;
			}
			
			if(matVO is ColorMaterialVO)
			{
				material = new ColorMaterial();
				material.fillAlpha = (matVO as ColorMaterialVO).fillAlpha;
				material.fillColor = (matVO as ColorMaterialVO).fillColor;
				
				return material;
			}
			
			if(matVO is TextMaterialVO)
			{
				modifyObjectSegments(_object3D);
				
				var text:String = (matVO as TextMaterialVO).text;
				var font:String = (matVO as TextMaterialVO).font;
				var fontSize:uint = (matVO as TextMaterialVO).fontSize;
				var fontColor:uint = (matVO as TextMaterialVO).fontColor;
				
				material = new TextMaterial(text, font, fontSize, fontColor, getTextDimensions(_object3D).x, getTextDimensions(_object3D).y);
				
				return material;
			}
			
			var clone3D:Object3DVO = (settings.objects3D[_object3D.name] as Object3DVO).clone() as Object3DVO;
			
			if(clone3D is SingleMaterialObject3DVO)
			{
				(clone3D as SingleMaterialObject3DVO).material = matVO;
			}
			
			if(clone3D is MaterialsListObject3DVO)
			{	
				(clone3D as MaterialsListObject3DVO).selectedFace = matVO.face;
				(clone3D as MaterialsListObject3DVO).materialsList[matVO.face] = matVO;
				
			}
			
			if(matVO is MovieMaterialVO)
			{
				material = null;
		
				facade.registerMediator(new SWFLoaderMediator(clone3D));
				
				return material;
			}
			
			if(matVO is VideoStreamMaterialVO)
			{
				material = null;
				
				trace("VID"+clone3D.x, clone3D.y, clone3D.z);

				facade.registerMediator(new VideoStreamMediator(clone3D));
				
				return material;
			}
			
		}
		
		
		protected function modifyObjectSegments(object3D:Object3DVO):void
		{
			if(object3D is PlaneVO)
			{
				(settings.scene.getChildByName((object3D as PlaneVO).name) as Plane).segmentsH = 8;
				(settings.scene.getChildByName((object3D as PlaneVO).name) as Plane).segmentsW = 8;
			}
			
			if(object3D is CubeVO)
			{
				(settings.scene.getChildByName((object3D as CubeVO).name) as Cube).segments = new Number3D(8, 8, 8);
			}
		}
		
		protected function getTextDimensions(object3D:Object3DVO):Point
		{
			var dimensions:Point = new Point();
			
			if(object3D is PlaneVO)
			{
				dimensions.x = (object3D as PlaneVO).scaleX * (object3D as PlaneVO).width;
				dimensions.y = (object3D as PlaneVO).scaleY * (object3D as PlaneVO).height;		
			} 
			
			if(object3D is CubeVO)
			{	
				if((object3D as CubeVO).selectedFace == CubeVO.BACK_FACE || (object3D as CubeVO).selectedFace == CubeVO.FRONT_FACE)
				{
					dimensions.x = (object3D as CubeVO).scaleX * (object3D as CubeVO).width;
					dimensions.y = (object3D as CubeVO).scaleY * (object3D as CubeVO).height;
			
				}
				
				if((object3D as CubeVO).selectedFace == CubeVO.TOP_FACE || (object3D as CubeVO).selectedFace == CubeVO.BOTTOM_FACE)
				{
					dimensions.x = (object3D as CubeVO).scaleX * (object3D as CubeVO).width;
					dimensions.y = (object3D as CubeVO).scaleZ * (object3D as CubeVO).depth;
				
				}
				
				if((object3D as CubeVO).selectedFace == CubeVO.LEFT_FACE || (object3D as CubeVO).selectedFace == CubeVO.RIGHT_FACE)
				{
					dimensions.x = (object3D as CubeVO).scaleZ * (object3D as CubeVO).depth;
					dimensions.y = (object3D as CubeVO).scaleY * (object3D as CubeVO).height;
				}

			}
			
			return dimensions;
		}
	}
}